#include <stdio.h>
#include <stdlib.h>

#include "main.h"
#include "static_file.h"
#include "xmalloc.h"
#include "url.h"

char static_files_dir[MAXPATHLEN+1];
static file_ext_array_t *files;
static dirlist_t *static_files;


static file_ext_array_t *
create_filext()
{
  return ( array_create(sizeof(file_ext_t *), 3) );
}

file_ext_t *
add_file(const char *ext, const char *mtype, dirlist_elem_t *delem)
{
  file_ext_t *fxt = (file_ext_t *) ncmalloc(1, sizeof(file_ext_t));
  assert(delem != NULL);
  fxt->ext = ext;
  fxt->mime = strdup(mtype);
  fxt->delem = delem;
  array_add_data(files, &fxt, 1);
  return (fxt);
}

file_ext_t *
get_file(const char *url)
{
  size_t idx;
  file_ext_t *fxt = NULL;

  for (idx = 0; idx < files->used; idx++) {
    fxt = *(file_ext_t **) array_get_offset(files, idx);
    if ( strcmp(get_string(fxt->delem->path), url) == 0 ) {
      return (fxt);
    }
  }
  return (NULL);
}

static void
free_filext(file_ext_array_t *arr)
{
  size_t i;
  file_ext_t *fxt = NULL;

  if (!arr) return;
  for (i = 0; i < arr->used; i++) {
    fxt = *(file_ext_t **) array_get_offset(arr, i);
    free((void *)fxt->mime);
    ncfree(fxt, sizeof(file_ext_t));
  }
  array_free(arr);
}

static dirlist_t *
list_static_files(const char *exts[])
{
  int i = 0;
  const char *ext;
  dirlist_t *result = NULL;

  while ( (ext = exts[i]) ) {
    result = listfiles(static_files_dir, (const char *)ext, result);
    i++;
  }
  return (result);
}

static const char *
get_mime_by_ext(const char *ext, const char *exts[], const char *mimes[]) {
  int i = 0;
  const char *tmp = NULL;

  assert(ext != NULL && exts != NULL);
  while ( (tmp = exts[i]) != NULL ) {
    if (strcmp(ext, tmp) == 0) {
      return (mimes[i]);
    }
    i++;
  }
  return (NULL);
}

bool
init_static_files(char *dir_path, const char *extensions[], const char *mimes[])
{
  size_t i = 0, ei = 0;
  dirlist_elem_t *elem = NULL;
  bool retval = true;
  const char *tmp;

  assert(dir_path != NULL);
  assert(extensions != NULL && mimes != NULL);
  memset(static_files_dir, 0, MAXPATHLEN+1);
  strncpy(static_files_dir, dir_path, MAXPATHLEN);
  files = create_filext();
  static_files = list_static_files(extensions);
  if (!static_files) return (false);
  I("loading static files in %s into the memory", static_files_dir);
  while( (elem = listfiles_foreach(static_files, &i)) != NULL )
  {
    D("loading %s ..", get_string(elem->path));
    if (!mmap_data(elem)) retval = false;
    if (get_strlen(elem->path) > strlen(static_files_dir)) {
      ei = strlen(static_files_dir);
    }
    if ((tmp = get_mime_by_ext(elem->ext, extensions, mimes))) {
      DD("static file: %s(%s) with %ld bytes", elem->ext, tmp, elem->siz);
      file_ext_t *f = add_file(elem->ext, tmp, elem);
      url_object_t *uo = url_register(get_string(elem->path)+ei, get_string(elem->path), URL_STATIC, (void *)elem->data);
      url_set_unused(uo, f);
    } else {
      W("No valid Extension: %s", elem->ext);
    }
  }
  return (retval);
}

void
free_static_files(void)
{
  free_filext(files);
  files = NULL;
  listfiles_cleanup(static_files);
  static_files = NULL;
}

